#!/usr/bin/env python3

import uuid
from Crypto.Cipher import AES
from scapy.all import *
from msfconsts import tlv_types, cmd_ids

enc_types = {0: "None", 1: "AES256", 2: "AES128"}
packet_types = {0: "Req", 1: "Resp"}
aes_key = bytes.fromhex('f2 00 3c 14 3d c8 43 6f 39 ad 6f 8f c4 c2 4f 3d 35 a3 5d 86 2e 10 b4 c6 54 ae dc 0e d9 dd 3a c5')
open('docs_backup.zip', 'w').close() # clear zip file


def xor(buf, key):
    return bytes([x ^ key[i % len(key)] for i, x in enumerate(buf)])


# pull all bytes into a stream
pcap = rdpcap("./msf.pcap")
stream = b"".join([bytes(packet[TCP].payload) for packet in pcap if TCP in packet])

i = 0
while i < len(stream):
    xor_head = stream[i:i+32]
    xor_key = xor_head[:4]
    head = xor(xor_head, xor_key)
    session_guid = head[4:20]
    enc_flag = int.from_bytes(head[20:24], "big")
    packet_len = int.from_bytes(head[24:28], "big")
    packet_type = int.from_bytes(head[28:32], "big")

    print(f"Packet: type={packet_types[packet_type]:<4} len={packet_len:<8} enc={enc_types[enc_flag]} sess={uuid.UUID(bytes=session_guid)}")

    tlv_data = xor(stream[i+32:i+packet_len+24], xor_key)
    if enc_flag == 1:
        aes_iv = tlv_data[:16]
        cipher = AES.new(aes_key, AES.MODE_CBC, iv=aes_iv)
        tlv_data = cipher.decrypt(tlv_data[16:])

    j = 0
    while j < len(tlv_data):
        l = int.from_bytes(tlv_data[j:j+4], 'big')
        if j + l > len(tlv_data) or l == 0:
            break
        t = int.from_bytes(tlv_data[j+4:j+8], 'big')
        v = tlv_data[j+8:j+l]
        if t == 0x20001: #COMMAND_ID
            v = cmd_ids[int.from_bytes(v[:4], 'big')]
        elif t == 0x40034: #CHANNEL_DATA
            with open('docs_backup.zip', 'ab') as f:
                f.write(v)
        if len(v) > 50:
            v = v[:50]
        print(f"TLV l={l:<8} t={tlv_types[t]:<26} v={v}")
        j += l
    
    i += 24 + packet_len

